home *** CD-ROM | disk | FTP | other *** search
- /* Folder routines.
-
- 93/10/13 aih created */
-
- #include <string.h>
- #include "pstr.h"
- #include "FolderLib.h"
-
- /* true if the folder exists */
- Boolean FolderExists(FileType *folder)
- {
- CInfoPBRec pb;
- volatile Boolean exists = true;
-
- TRY {
- if (exists) {
- FileCatalog(folder, &pb);
- exists = ((pb.dirInfo.ioFlAttrib & (1 << kFolderBit)) != 0);
- }
- } CATCH {
- if (FailReason() == fnfErr) {
- exists = false;
- RETRY;
- }
- } ENDTRY;
- return(exists);
- }
-
- /* count files */
- static Boolean valence(const CInfoPBRec *pb, void *data)
- {
- (*(long *) data)++;
- return(false);
- }
-
- /* return number of items in folder */
- long FolderValence(FileType *folder, Boolean recursive)
- {
- CInfoPBRec pb;
- long count = 0;
-
- require(FolderExists(folder));
- if (! recursive) {
- FileCatalog(folder, &pb);
- count = pb.dirInfo.ioDrNmFls;
- }
- else
- FolderScan(folder, true, valence, &count);
- return(count);
- }
-
- /* data used while scanning folders, made external to routine to keep
- stack memory usage low during recursive calls */
- struct fsdata {
- Boolean (*action)(const CInfoPBRec *pb, void *data);
- void *data; /* data for action function */
- CInfoPBRec pb; /* parameter block returned by PBGetCatInfo */
- Boolean recursive; /* if true, descends subdirectories */
- Boolean stop; /* if true, operation is stopped */
- FilePNameType name; /* name of file returned by PBGetCatInfo */
- };
-
- static void DoScan(struct fsdata *fsdata, FileDirType dir)
- {
- short index;
- long mod;
- OSErr err;
-
- for (index = 1; ! fsdata->stop; index++) {
-
- /* check if directory's file structure has changed, since index
- will no longer be valid if files have been added or removed
- by other processes */
- fsdata->pb.dirInfo.ioFDirIndex = -1;
- fsdata->pb.dirInfo.ioDrDirID = dir;
- FailOSErr(PBGetCatInfo(&fsdata->pb, false));
- check((fsdata->pb.dirInfo.ioFlAttrib & (1 << kFolderBit)) != 0);
- if (index == 1) /* first time, remember mod date */
- mod = fsdata->pb.dirInfo.ioDrMdDat;
- else if (mod != fsdata->pb.dirInfo.ioDrMdDat) /* verify thereafter */
- FailOSErr(paramErr); /* not the best error number... */
-
- /* get data for indexed item */
- fsdata->pb.dirInfo.ioFDirIndex = index;
- fsdata->pb.dirInfo.ioDrDirID = dir;
- fsdata->pb.dirInfo.filler2 = 0; /* ioACUser */
- err = PBGetCatInfo(&fsdata->pb, false);
- if (err == fnfErr) break;
- FailOSErr(err);
-
- /* process file or subdirectory */
- fsdata->stop = fsdata->action(&fsdata->pb, fsdata->data);
- if (! fsdata->stop && fsdata->recursive &&
- (fsdata->pb.dirInfo.ioFlAttrib & (1 << kFolderBit)) != 0)
- {
- DoScan(fsdata, fsdata->pb.dirInfo.ioDrDirID);
- }
- }
- }
-
- /* Execute the function specified by 'action' for each file and folder
- in the folder specified by 'folder'. If 'resursive' is true then
- subfolders are descended recursively. The 'data' parameter is
- passed to the 'action' function and may contain any user defined
- data. The action function should return true to halt processing. */
- void FolderScan(FileType *fp, Boolean recursive,
- Boolean (*action)(const CInfoPBRec *pb, void *data), void *data)
- {
- struct fsdata fsdata;
- FileType folder;
-
- require(FolderExists(fp));
- require(action != NULL);
- FileClone(fp, &folder);
- FileDirID(&folder);
- memclr(&fsdata, sizeof(struct fsdata));
- fsdata.action = action;
- fsdata.data = data;
- fsdata.recursive = recursive;
- pstrcpy(fsdata.name, folder.pnm);
- fsdata.pb.dirInfo.ioNamePtr = fsdata.name;
- fsdata.pb.dirInfo.ioVRefNum = folder.vol;
- fsdata.pb.dirInfo.ioDrDirID = folder.dir;
- DoScan(&fsdata, folder.dir);
- }
-
- /* create the folder */
- void FolderCreate(FileType *folder)
- {
- FileDirType dir;
-
- require(FileValid(folder));
- FailOSErr(DirCreate(folder->vol, folder->dir, folder->pnm, &dir));
- ensure(FolderExists(folder));
- }
-
- /* delete the folder */
- void FolderDelete(FileType *folder)
- {
- FileDelete(folder);
- }
-
-